﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.ServiceModel;
using System.Text.RegularExpressions;
using System.Threading;
using System.Runtime.Serialization;

namespace WcfService
{
    [ServiceContract(Namespace = "http://WcfService")]
    public partial interface IService
    {
        [OperationContract]
        DataSet dsQuery(string query);

        [OperationContract]
        DataSet ExecuteDataset(string commandText, Dictionary<string, object> d);

        [OperationContract]
        int ExecuteNonQuery(string commandText, Dictionary<string, object> d);

        [OperationContract]
        object ExecuteScalar(string commandText, Dictionary<string, object> d);
    }

    public partial class Service : IService
    {
        //static SqlConnection dbConn = new SqlConnection(ConfigurationUtil.GetConnectionSetting("Lib_DAL.Properties.Settings.ConnectionString"));

        public DataSet dsQuery(string sqlQuery)
        {
            DataSet retVal = null;
            SqlConnection dbConn = new SqlConnection(Properties.Settings.Default.ConnectionString);
            Regex regex = new Regex("^GO", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            string[] lines = regex.Split(sqlQuery);
            retVal = new DataSet();

            foreach (string line in lines)
            {
                SqlCommand dbCmd = new SqlCommand(line, dbConn);
                dbCmd.CommandType = CommandType.Text;
                dbCmd.CommandTimeout = 500;
                SqlDataAdapter da = null;

                //SqlTransaction transaction =null;     //khai báo một transaction

                try
                {
                    dbConn.Open();
                    //transaction = dbConn.BeginTransaction();    //bắt đầu quá trình quản lý transaction
                    //dbCmd.Transaction = transaction;

                    da = new SqlDataAdapter(dbCmd);
                    da.Fill(retVal);


                    //transaction.Commit();      //cam kết thực hiện thành công
                }
                //catch (Exception e)    //nếu xảy ra lỗi
                //{
                //    //hiển thị thông báo lỗi tại đây

                //    //transaction.Rollback();     //quay lùi
                //}
                finally
                {
                    //transaction.Dispose();
                    da.Dispose();
                    retVal.Dispose();
                    dbConn.Dispose();
                }
            }
            return retVal;
        }

        public DataSet ExecuteDataset(string commandText, Dictionary<string, object> d)
        {
            object[] parameterValues = DicAndParam.ToParams(d);

            return SqlHelper.ExecuteDataset(new SqlConnection(Properties.Settings.Default.ConnectionString), commandText, parameterValues);
        }


        public int ExecuteNonQuery(string commandText, Dictionary<string, object> d)
        {
            object[] parameterValues = DicAndParam.ToParams(d);
            return SqlHelper.ExecuteNonQuery(new SqlConnection(Properties.Settings.Default.ConnectionString), commandText, parameterValues);
        }


        public object ExecuteScalar(string commandText, Dictionary<string, object> d)
        {
            object[] parameterValues = DicAndParam.ToParams(d);
            return SqlHelper.ExecuteScalar(new SqlConnection(Properties.Settings.Default.ConnectionString), commandText, parameterValues);
        }

    }

    [DataContract(Namespace = "http://WcfService")]
    public class MainService_Info
    {
        //no thing
    }

    // Custom call object that is passed back to WCF so WCF knows when to call the End method
    public class DataAsyncResult : IAsyncResult, IDisposable
    {
        // To store the callback and state passed from WCF
        AsyncCallback callback;
        object state;

        // For the implementation of IAsyncResult.AsyncCallback
        ManualResetEvent waithandle;

        // Guard object for thread sync
        object guard = new object();

        // complete flag that is set to true on completion (supports IAsyncResult.IsCompleted)
        bool complete;


        // Store the callback and state passed by WCF
        public DataAsyncResult(AsyncCallback callback, object state)
        {
            this.callback = callback;
            this.state = state;
        }

        // Called by service to set the call object to a completed state
        public void Complete()
        {
            // flag as complete
            complete = true;

            // signal the event object
            if (waithandle != null)
            {
                waithandle.Set();
            }

            // Tell WCF the call is complete
            if (callback != null)
            {
                callback(this);
            }
        }

        #region IAsyncResult Members

        public object AsyncState
        {
            get { return state; }
        }

        // Use double check locking for efficient lazy allocation of the event object
        public WaitHandle AsyncWaitHandle
        {
            get
            {
                if (waithandle == null)
                {
                    lock (guard)
                    {
                        if (waithandle == null)
                        {
                            waithandle = new ManualResetEvent(false);
                        }
                    }
                }

                return waithandle;
            }
        }

        public bool CompletedSynchronously
        {
            get { return false; }
        }

        public bool IsCompleted
        {
            get { return complete; }
        }

        #endregion

        #region IDisposable Members

        // Clean up the event if it got allocated
        public void Dispose()
        {
            if (waithandle != null)
            {
                waithandle.Close();
            }
        }

        #endregion
    }

  }
